import java.awt.Canvas;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.awt.image.BufferedImage;

import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.Timer;
import javax.swing.WindowConstants;
/**
 * Handles all display functions on the board and user input
 */
@SuppressWarnings("serial")
public class Board extends Canvas implements MouseListener, ActionListener, WindowListener, WindowStateListener {
    /**
	 * these all need to be commented on because it looks awful
	 */
	//instance variables
    Player[] players;
    Card[][] hands;
    Card[] cardsPlayed = new Card[4];
    Card c = null;   
    Deck deck = new Deck();
    String mousePos = "";
    boolean handsDrawn = true;
    boolean cardPlayed = false;
    boolean canPlay = false;
    boolean firstRound = true;
    boolean mainMenuBeenDisplayed = false;
    Timer t = new Timer(1000,this);
    int[] playerBets = new int[4];
    int[] handsWon = new int[4];
    int index;   
    int min = 0;
    int sec = 0;
    int playingPos = 0;
    int leader = 0;
    int nsScore = 0;
    int ewScore = 0;
    int nsBags = 0;
    int ewBags = 0;
    int suitLed = 4;
    int answer = -1;
    int scoreLimit;
    String time = min+":"+sec;
    Graphics graphToBack;
    Graphics2D twoDGraph;
    BufferedImage back;   
    State state;
    JFrame mainMenu = new JFrame("Main Menu");
    JFrame settings = new JFrame("Settings");
    Spades spad = null;
    JFrame spades = null;
    Settings variables;
	
    public Board(Spades spa)
    {
    	spades = spa;
    	spades.setVisible(false);
        deck.dealHands();
        hands = deck.getHands();
        addMouseListener(this);
        setVisible(true);
    }

    @Override
    public void paint(Graphics window) {
		twoDGraph = (Graphics2D)window;
        if(back==null)
		   back = (BufferedImage)(createImage(getWidth(),getHeight()));
		graphToBack = back.createGraphics();
    	if(state.getState()>2)
    	{
    		if(!t.isRunning())
    			t.start();
    		setBackground(variables.getBackGroundColor());
			graphToBack.clearRect(0, 0, getWidth(), getHeight());
			graphToBack.setFont(Font.getFont("Times New Roman"));
	    	//N/S scores
			graphToBack.drawString(time,800,30);
			graphToBack.drawString("Score", 625, 30);
	        graphToBack.drawString("Bags",660,30);
	        graphToBack.drawString("Bids",695,30);
	        graphToBack.drawString("Taken",725,30);
	        graphToBack.drawString("N/S:    ",600,40);
	        graphToBack.drawString(""+nsScore,635,40);
	        graphToBack.drawString(state.getNSBags()+"", 670, 40);
	        graphToBack.drawString(""+(playerBets[0]+playerBets[2]), 705, 40);
	        graphToBack.drawString(""+(handsWon[0]+handsWon[2]), 735, 40);
	        //E/W scores
	        graphToBack.drawString("E/W:    ",600,50);
	        graphToBack.drawString(""+ewScore,635,50);
	        graphToBack.drawString(""+state.getEWBags(), 670, 50);
	        graphToBack.drawString(""+(playerBets[1]+playerBets[3]), 705, 50);
	        graphToBack.drawString(""+(handsWon[1]+handsWon[3]), 735, 50);
	        if(!handsDrawn)
	        {
	            drawCleanBoard(graphToBack);
	            drawHandsOnBoard(graphToBack);
	        }
	        if(cardPlayed)
	        {
	            playSelectedCard(index, playingPos);
	            cardPlayed = false;
	        }
	        for(int ctr = 0; ctr<4; ctr++)
	        {
	        	if(cardsPlayed[0]!=null)
	        		graphToBack.drawImage(cardsPlayed[0].getCardImage(), 385,300, this);
	        	if(cardsPlayed[1]!=null)
	        		graphToBack.drawImage(cardsPlayed[1].getCardImage(), 300,225, this);
	        	if(cardsPlayed[2]!=null)
	        		graphToBack.drawImage(cardsPlayed[2].getCardImage(), 385,170, this);
	        	if(cardsPlayed[3]!=null)
	        		graphToBack.drawImage(cardsPlayed[3].getCardImage(), 470,225, this);
	       	}
	        drawOnNamePlates(graphToBack);
	        window.drawImage(back,0,0,this);
    	}
    }
    
    public void update(Graphics g)
    {  
    	paint(g);
    }
    /*
     * draws in the white rectangles around the screen, placing info like names and individual scores in them
     */
    public void drawOnNamePlates(Graphics window)
    {
    	window.drawString("Player South: "+variables.getPlayerName(), 263, 415);
    	window.drawString("Player Bid: "+playerBets[0], 263, 430);
    	window.drawString("Hands Taken: "+handsWon[0], 263, 445);
    	
    	window.drawString("Player North: Nick McCleerey", 263, 118);
    	window.drawString("Player Bid: "+playerBets[2], 263, 133);
    	window.drawString("Hands Taken: "+handsWon[2], 263, 133+15);
    	
    	window.drawString("Player West: ", 145, 235);
    	window.drawString("Lucky Charms", 145, 250);
    	window.drawString("Player Bid: "+playerBets[1], 145, 265);
    	window.drawString("Hands Taken: "+handsWon[1], 145, 280);
    	
    	window.drawString("Player East: ", 577, 235);
    	window.drawString("Tony the Tiger", 577, 250);
    	window.drawString("Player Bid: "+playerBets[3], 577, 265);
    	window.drawString("Hands Taken: "+handsWon[3], 577, 280);
    }
    /*
     * sets up the initial view for the cards and score boxes
     */
    public void drawCleanBoard(Graphics window) {
        window.setColor(Color.white);
        window.drawRoundRect(260, 400, 313, 60, 15, 15); //player 0 box
        window.drawRoundRect(574, 210, 120, 143, 15, 15);//player 1 box
        window.drawRoundRect(260, 103, 313, 60, 15, 15); //player 2 box
        window.drawRoundRect(140, 210, 120, 143, 15, 15);//player 3 box
        window.drawRoundRect(590, 5, 240, 96, 15, 15);   //score box
    }
    /*
     * is not called by drawCleanBoard() this method draws all the hands on the board.
     * if it is not the players hand it is drawing then it draws the back of a card
     * so the user can only see their hand and not everyone else
     */
    public void drawHandsOnBoard(Graphics g) {
    	//hands[h][cards].getBackOfCard()
        for(int h = 0; h<4; h++)
        {
            for(int cards = 0; cards<13; cards++)
            {
                if(h == 0 && hands[h][cards]!=null)
                {
                    if(cards<7)
                        g.drawImage(hands[h][cards].getCardImage(), 150+(73*cards), 465, this);
                    else
                        g.drawImage(hands[h][cards].getCardImage(), 180+(73*(cards-7)), 562, this);
                }
                else if(h == 1 && hands[h][cards]!=null)
                {
                    g.drawImage(hands[h][cards].getBackOfCard(), 63, 115+(20*cards), this);                    
                }
                else if(h == 2 && hands[h][cards]!=null)
                {
                    g.drawImage(hands[h][cards].getBackOfCard(), 260+(20*cards), 5, this);
                }                 
                else if(h == 3 && hands[h][cards]!=null)
                {
                	g.drawImage(hands[h][cards].getBackOfCard(), 702, 115+(20*cards), this);
                }
            }
        }
    }
    /*
     * drives the Board class as directed from State which is also updated by Spades
     */
    public void update(State s) {
    	state = s;
    	if(variables == null)
    		variables = new Settings(state);
        switch(s.getState())
        {
        	case 0: mainMenu.setEnabled(true);
					if(settings.isVisible())
					{
						settings.setVisible(false);
						mainMenu.setVisible(true);
					}
        			if(!mainMenu.isVisible())
		        	{
		        		mainMenu = new JFrame("Main Menu");
		        		displayMainMenu();
		        	}
        			mainMenu.setVisible(true);
		        	break;
        	case 1: if(!settings.isVisible())
		        	{
        				settings = new JFrame("Settings");
        				displaySettings();
		        	}
		        	break;
        	case 2: //implement statistics
		        	break;
          	case 3: if(!variables.getBreakSpadesFirst())
          				state.setSpadesAllowed();
          			spades.setEnabled(true);
          			spades.setVisible(true);
          			scoreLimit = variables.getScoreLimit();
          			//state.setDealer(variables.getLeader());
          			spades.setVisible(true);
          			spades.setAlwaysOnTop(false);
          			cardsPlayed = new Card[4];
          			playerBets = new int[4];
            		repaint(); 
            		handsDrawn = false; 
            		s.setState(s.getState()+1); 
            		break;
            case 4: setHands(s); 
            		s.setState(s.getState()+1); 
            		break;
            case 5: if(firstRound) 
            		{
            			playBets(s);
            			firstRound = false;
            		}
            		s.setState(s.getState()+1); 
            		break;
            case 6: int ctr = 0;
            		while(ctr<13){
            			repaint();
            			playRound(s); 
            			ctr++;};
            		s.setState(s.getState()+1);
            		break;
            case 7: displayScores(s); 
            		s.setState(s.getState()+1);
            		break;
            case 8: if(s.getNSScore()<500 && s.getEWScore()<500)
		            {
            			s.setRound(s.getRound()+1);
            			s.setState(3);
            			s.setDealer(s.getDealer()+1);
            			s.setEWBags(ewBags);
            			s.setEWScore(ewScore);
            			s.setNSBags(nsBags);
            			s.setNSScore(nsScore);
            			
            			firstRound= true;
            			graphToBack = null;
            			back = null;
            			twoDGraph = null;
                		if(s.getDealer()+1>3)
                			leader = 0;
                		else
                			leader = s.getDealer();
                		displayGameScore(s);
                		handsWon = new int[4];
		            }
            		else if(s.getNSScore()>s.getEWScore())
            		{
            			System.out.println("Nick McCleerey && Andrew Markley Win!");
            			System.out.println("N/S Score: " + s.getNSScore());
            			System.out.println("East && West Lose.");
            			System.out.println("E/W Score: " + s.getEWScore());
            			s.setState(s.getState()+1);
            		}
            		else if(s.getEWScore()>s.getNSScore())
            		{
            			System.out.println("East && West Win!");
            			System.out.println("E/W Score: " + s.getEWScore());             			
            			System.out.println("Nick McCleerey && Andrew Markley lose.");
            			System.out.println("N/S Score: " + s.getNSScore());
            			s.setState(s.getState()+1);
            		}
            		break;
            case 9: System.out.println("TADA GAME OVER!"); break;
            case 10: ; break;
            default: break;
        }
    }
    
    @SuppressWarnings("unused")
	private void displayStats() {

	}
    
    private void displaySettings() {
    	settings = variables.getJFrame();
    	boolean mainmenu = false;
    	if(mainMenu.isVisible())
    	{
    		mainMenu.setEnabled(false);
    		mainmenu = true;
    	}
    	//if(spades.isVisible())
    		//spades.setEnabled(false);
    	settings.setVisible(true);
    	variables.setShowing(mainmenu);
    	settings.addWindowListener(this);
    	settings.addWindowStateListener(this);
	}
    /*
     * handles display and layout of the main menu
     */
    private void displayMainMenu()
    {
    	mainMenu.setSize(855,700);
    	mainMenu.setLocation(200, 40);
		mainMenu.setLayout(new FlowLayout());
		mainMenu.setResizable(false);
		mainMenu.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        JLabel background = new JLabel(new ImageIcon(getClass().getResource("/resources/Spades.jpg")));
        background.setBounds(-5, -5, getWidth(), getHeight());
        mainMenu.getLayeredPane().add(background, new Integer(Integer.MIN_VALUE));
        background.setOpaque(false);
        mainMenu.add(background);
        
		JButton newGame = new JButton("New Game!");
		newGame.setVerticalTextPosition(AbstractButton.CENTER);
	    newGame.setActionCommand("New Game");
	    newGame.setBounds(345, 420, 145, 30);
	    newGame.addActionListener(this);
	    
		JButton settings = new JButton("Settings");
		settings.setVerticalTextPosition(AbstractButton.BOTTOM);
		settings.setActionCommand("Settings");
		settings.setBounds(345, 455, 145, 30);
		settings.addActionListener(this);
		
		JButton stats = new JButton("Statistics");
		stats.setVerticalTextPosition(AbstractButton.BOTTOM);
		stats.setActionCommand("Stats");
		stats.setBounds(345, 490, 145, 30);
		stats.addActionListener(this);
		
		JButton exit = new JButton("Exit :(");
		exit.setVerticalTextPosition(AbstractButton.BOTTOM);
		exit.setActionCommand("exit");
		exit.setBounds(345, 490+35, 145, 30);
		exit.addActionListener(this);
		
		Font f = new Font("Times New Roman", Font.BOLD, 14);
		JLabel andrew = new JLabel("Created by: Andrew Markley & Nick McCleerey");
		andrew.setForeground(Color.white);
		andrew.setFont(f);
		andrew.setBounds(480, 345, 300, 20);
		
		mainMenu.getLayeredPane().add(andrew,1);
		mainMenu.getLayeredPane().add(newGame,1);
		mainMenu.getLayeredPane().add(settings,1);
		mainMenu.getLayeredPane().add(stats,1);
		mainMenu.getLayeredPane().add(exit,1);
		
		mainMenu.setAlwaysOnTop(false);
		if(!mainMenu.isVisible() && !mainMenuBeenDisplayed)
		{
			mainMenu.setVisible(true);
			mainMenuBeenDisplayed = true;
		}
    }
	/*
     * handles displaying the end round scores
     */
    private void displayGameScore(State s)
    {
    	String display = "        Score  Bags  Bid  Taken\n"
    		+"N/S:   "+s.getNSScore()+"        "+s.getNSBags()+"        " +(playerBets[0]+playerBets[2]) +"        "+(handsWon[0]+handsWon[2])+"\n";
    	display+= "E/W:  "+s.getEWScore()+"        "+s.getEWBags()+"        " +(playerBets[1]+playerBets[3]) +"        "+(handsWon[1]+handsWon[3])+"\n";;
    	JOptionPane.showConfirmDialog(Spades.getFrames()[0], display, "Game Over!",JOptionPane.OK_CANCEL_OPTION);
    }
    /*
     * will eventually display the scores of a successful 13 rounds
     */
    private void displayScores(State s) {
    	nsBags = s.getNSBags();
    	ewBags = s.getEWBags();
    	nsScore = s.getNSScore();
    	ewScore = s.getEWScore();
    	if(playerBets[0]+playerBets[2]>=10 && handsWon[0]+handsWon[2]==playerBets[0]+playerBets[2])
    		nsScore+=100;
    	if(playerBets[0]== 0 && handsWon[0] ==0 || playerBets[2]==0 && handsWon[2]==0)
    		nsScore+=100;
    	else if(playerBets[0]== 0 && handsWon[0] !=0 || playerBets[2]==0 && handsWon[2]!=0)
    		nsScore-=100;
    	if(playerBets[0]+playerBets[2]==handsWon[0]+handsWon[2])
    		nsScore+=(playerBets[0]+playerBets[2])*10;
    	else if(playerBets[0]+playerBets[2]>handsWon[0]+handsWon[2])
    		nsScore+=-100;
    	else
    	{
    		nsScore+=(handsWon[0]+handsWon[2])*10;
    		nsBags+=(handsWon[0]+handsWon[2])-(playerBets[0]+playerBets[2]); 
    	}
    	if(nsBags%10==0 && nsBags!=0)
    	{
    		nsScore+=-100;
    		nsBags = 0;
    	}
    	if(playerBets[1]+playerBets[3]>=10 && handsWon[1]+handsWon[3]==playerBets[1]+playerBets[3])
    		ewScore+=100;
    	if(playerBets[1]== 0 && handsWon[1] ==0 || playerBets[3]==0 && handsWon[3]==0)
    		ewScore+=100;
    	else if(playerBets[1]== 0 && handsWon[1] !=0 || playerBets[3]==0 && handsWon[3]!=0)
    		ewScore-=100;
    	if(playerBets[1]+playerBets[3]==handsWon[1]+handsWon[3])
    		ewScore+=(playerBets[1]+playerBets[3])*10;
    	else if(playerBets[1]+playerBets[3]>handsWon[1]+handsWon[3])
    		ewScore+=-100;
    	else
    	{
    		ewScore+=(handsWon[1]+handsWon[3])*10;
    		ewBags+=(handsWon[1]+handsWon[3])-(playerBets[1]+playerBets[3]); 
    	}
    	if(ewBags%10==0 && ewBags!=0)
    	{
    		ewScore+=-100;
    		ewBags = 0;
    	}
    	s.setNSBags(nsBags);
    	s.setNSScore(nsScore);
    	s.setEWScore(ewScore);
    	s.setEWBags(ewBags);
	}
    /*
     * returns the winner of a hand after all 4 cards have been played
     */
    public void getWinner(State s)
    {
    	int winner = leader;
    	boolean spadePlayed = false;
    	for(int ctr = 0; ctr<4; ctr++)
    	{
    		if(cardsPlayed[ctr].getSuit()==0)
    			spadePlayed = true;
    	}
    	if(spadePlayed)
    		s.setSpadesAllowed();
    	for(int ctr = 0; ctr<4; ctr++)
    	{
    		if(spadePlayed)
    			if(cardsPlayed[ctr].getSuit()==0)
    			{
    				if(cardsPlayed[winner].getSuit()!=0)
    					winner = ctr;
    				else if(cardsPlayed[ctr].getValue()>cardsPlayed[winner].getValue())
    					winner = ctr;
    			}
    			else{}
    		else
    			if(cardsPlayed[ctr].getSuit()==cardsPlayed[leader].getSuit())
    			{
    				if(cardsPlayed[ctr].getValue()>cardsPlayed[winner].getValue())
    					winner = ctr;
    			}
    	}
    	handsWon[winner]++;
    	leader = winner;
    	try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
    	for(int ctr = 0; ctr<4; ctr++)
    		cardsPlayed[ctr] = null;
    }
	/*
     * this method is a wreck but it controls which player goes first and when others play
     */
    public void playRound(State s)
    {
		int partnerPos;
    	if(leader==0)
        {
    		//player 0 (south)
    		playingPos = 0;
    		partnerPos = 2;
        	canPlay = true; 
        	while(cardsPlayed[playingPos]==null){ 
        		try {
					Thread.sleep(5);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
    		} 
    		if(c!=null){
    			s.updateHands(hands);
    			cardsPlayed[0] = c;
    		}
    		canPlay = false;
    		pause();
    		//player 1 (east)
    		playingPos = 1;
    		partnerPos = 3;
    		Player p = new Player(hands[1], cardsPlayed[0].getSuit(), s.getSpadesAllowed(),cardsPlayed,playerBets,handsWon,partnerPos,playingPos);
    		p.chooseComputerCard();
    		cardsPlayed[1] = p.getCardToPlay();
    		playSelectedCard(p.getCardToPlayPos(), playingPos);
    		s.updateHands(hands);
    		pause();
    		//player 2 (north)
    		playingPos = 2;
    		partnerPos = 0;
    		p = new Player(hands[2], cardsPlayed[0].getSuit(), s.getSpadesAllowed(),cardsPlayed,playerBets,handsWon,partnerPos,playingPos);
    		p.chooseComputerCard();
    		cardsPlayed[2] = p.getCardToPlay();
    		playSelectedCard(p.getCardToPlayPos(), playingPos);
    		s.updateHands(hands);
    		pause();
    		//player 3 (west)
    		playingPos = 3;
    		partnerPos = 1;
    		p = new Player(hands[3], cardsPlayed[0].getSuit(), s.getSpadesAllowed(),cardsPlayed,playerBets,handsWon,partnerPos,playingPos);
    		p.chooseComputerCard();
    		cardsPlayed[3] = p.getCardToPlay();
    		playSelectedCard(p.getCardToPlayPos(), playingPos);
    		s.updateHands(hands);
        }
    	if(leader==1)
        {
    		//player 1 (east)
    		playingPos = 1;
    		partnerPos = 3;
    		Player p = new Player(hands[1], 4, s.getSpadesAllowed(),cardsPlayed,playerBets,handsWon,partnerPos,playingPos);
    		p.chooseComputerCard();
    		cardsPlayed[1] = p.getCardToPlay();
    		playSelectedCard(p.getCardToPlayPos(), playingPos);
    		s.updateHands(hands);
    		pause();
    		suitLed = cardsPlayed[1].getSuit();
    		//player 2 (north)
    		playingPos = 2;
    		partnerPos = 0;
    		p = new Player(hands[2], cardsPlayed[1].getSuit(), s.getSpadesAllowed(),cardsPlayed,playerBets,handsWon,partnerPos,playingPos);
    		p.chooseComputerCard();
    		cardsPlayed[2] = p.getCardToPlay();
    		playSelectedCard(p.getCardToPlayPos(), playingPos);
    		s.updateHands(hands);
    		pause();
    		//player 3 (west)
    		playingPos = 3;
    		partnerPos = 1;
    		p = new Player(hands[3], cardsPlayed[1].getSuit(), s.getSpadesAllowed(),cardsPlayed,playerBets,handsWon,partnerPos,playingPos);
    		p.chooseComputerCard();
    		cardsPlayed[3] = p.getCardToPlay();
    		playSelectedCard(p.getCardToPlayPos(), playingPos);
    		s.updateHands(hands);
    		//player 0 (south)
    		playingPos = 0;
    		partnerPos = 2;
        	canPlay = true; 
        	while(cardsPlayed[playingPos]==null){ 
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
    		} 
    		if(c!=null){
    			s.updateHands(hands);
    			cardsPlayed[0] = c;
    		}
    		canPlay = false;
        }
    	if(leader == 2)
    	{
    		//player 2 (north)
    		playingPos = 2;
    		partnerPos = 0;
    		Player p = new Player(hands[2], 4, s.getSpadesAllowed(),cardsPlayed,playerBets,handsWon,partnerPos,playingPos);
    		p.chooseComputerCard();
    		cardsPlayed[2] = p.getCardToPlay();
    		playSelectedCard(p.getCardToPlayPos(), playingPos);
    		s.updateHands(hands);
    		pause();
    		suitLed = cardsPlayed[2].getSuit();
    		//player 3 (west)
    		playingPos = 3;
    		partnerPos = 1;
    		p = new Player(hands[3], cardsPlayed[2].getSuit(), s.getSpadesAllowed(),cardsPlayed,playerBets,handsWon,partnerPos,playingPos);
    		p.chooseComputerCard();
    		cardsPlayed[3] = p.getCardToPlay();
    		playSelectedCard(p.getCardToPlayPos(), playingPos);
    		s.updateHands(hands);
    		pause();
    		//player 0 (south)
    		playingPos = 0;
    		partnerPos = 2;
        	canPlay = true; 
        	while(cardsPlayed[playingPos]==null){ 
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
    		} 
    		if(c!=null){
    			s.updateHands(hands);
    			cardsPlayed[0] = c;
    		}
    		canPlay = false;
    		pause();
    		//player 1 (east)
    		playingPos = 1;
    		partnerPos = 3;
    		p = new Player(hands[1], cardsPlayed[2].getSuit(), s.getSpadesAllowed(),cardsPlayed,playerBets,handsWon,partnerPos,playingPos);
    		p.chooseComputerCard();
    		cardsPlayed[1] = p.getCardToPlay();
    		playSelectedCard(p.getCardToPlayPos(), playingPos);
    		s.updateHands(hands);
    	}
    	if(leader == 3)
    	{
    		//player 3 (west)
    		playingPos = 3;
    		partnerPos = 1;
    		Player p = new Player(hands[3], 4, s.getSpadesAllowed(),cardsPlayed,playerBets,handsWon,partnerPos,playingPos);
    		p.chooseComputerCard();
    		cardsPlayed[3] = p.getCardToPlay();
    		playSelectedCard(p.getCardToPlayPos(), playingPos);
    		s.updateHands(hands);
    		pause();
    		suitLed = cardsPlayed[3].getSuit();
    		//player 0 (south)
    		playingPos = 0;
    		partnerPos = 2;
        	canPlay = true; 
        	while(cardsPlayed[playingPos]==null){ 
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
    		} 
    		if(c!=null){
    			s.updateHands(hands);
    			cardsPlayed[0] = c;
    		}
    		canPlay = false;
    		pause();
    		//player 1 (east)
    		playingPos = 1;
    		partnerPos = 3;
    		p = new Player(hands[1], cardsPlayed[3].getSuit(), s.getSpadesAllowed(),cardsPlayed,playerBets,handsWon,partnerPos,playingPos);
    		p.chooseComputerCard();
    		cardsPlayed[1] = p.getCardToPlay();
    		playSelectedCard(p.getCardToPlayPos(), playingPos);
    		s.updateHands(hands);
    		pause();
    		//player 2 (north)
    		playingPos = 2;
    		partnerPos = 0;
    		p = new Player(hands[2], cardsPlayed[3].getSuit(), s.getSpadesAllowed(),cardsPlayed,playerBets,handsWon,partnerPos,playingPos);
    		p.chooseComputerCard();
    		cardsPlayed[2] = p.getCardToPlay();
    		playSelectedCard(p.getCardToPlayPos(), playingPos);
    		s.updateHands(hands);
    	}
    	suitLed = 4;
		getWinner(s);
    }
    /*
     * decides and allows play in the specific order as dictated by the rules
     */
    public void playBets(State s)
    {
    	Player p = null;
    	switch(s.getDealer())
    	{
    		case 0: //player 0
	    	    	playerBets[0] = getPlayerBet();
	    	    	//player 1
	    	    	p = new Player(s.getHand(1));
	    	    	playerBets[1] = p.getComputerBet();
	    	    	//player 2
	    	    	p = new Player(s.getHand(2));
	    	    	playerBets[2] = p.getComputerBet();
	    	    	//player 3
	    	    	p = new Player(s.getHand(3));
	    	    	playerBets[3] = p.getComputerBet();
	    	    	break;
    		case 1: //player 1
	    	    	p = new Player(s.getHand(1));
	    	    	playerBets[1] = p.getComputerBet();
	    	    	//player 2
	    	    	p = new Player(s.getHand(2));
	    	    	playerBets[2] = p.getComputerBet();
	    	    	//player 3
	    	    	p = new Player(s.getHand(3));
	    	    	playerBets[3] = p.getComputerBet();
	    	    	repaint();
	    	    	//player 0
	    	    	playerBets[0] = getPlayerBet(); break;
    		case 2: //player 2
    	    	p = new Player(s.getHand(2));
    	    	playerBets[2] = p.getComputerBet();
    	    	//player 3
    	    	p = new Player(s.getHand(3));
    	    	playerBets[3] = p.getComputerBet();
    	    	//player 0
    	    	repaint();
    	    	playerBets[0] = getPlayerBet();
    	    	//player 1
    	    	p = new Player(s.getHand(1));
    	    	playerBets[1] = p.getComputerBet(); break;
    		case 3: //player 3
	    	    	p = new Player(s.getHand(3));
	    	    	playerBets[3] = p.getComputerBet();
	    	    	repaint();
	    	    	//player 0
	    	    	playerBets[0] = getPlayerBet();
	    	    	//player 1
	    	    	p = new Player(s.getHand(1));
	    	    	playerBets[1] = p.getComputerBet();
	    	    	//player 2
	    	    	p = new Player(s.getHand(2));
	    	    	playerBets[2] = p.getComputerBet();
	    	    	break;
    		default: System.out.println("HI MOM!");break; 
    	}
    }
    /*
     * This method determines whether the user clicked on a card with the left
     * mouse button and if it should play the selected card.
     */
    public void mousePressed(MouseEvent e) {
        if(state.getState()>2 && canPlay && e.getButton()==1)
        {
            int x = e.getX();
            int y = e.getY();
            mousePos = x+" "+y;
            index = getSelectedCard(x,y);
            if(index!=-1 && hands[0][index]!=null)
                cardPlayed = true;
            if(index!=-1 && !isValidPlay(hands[0][index]))
            	cardPlayed = false;
            repaint();
            return;
        }
    }
    /*
     * places the selected card from the user into the playing arena and removes
     * card from players hand by making it null. then calls repaint()
     */
    private void playSelectedCard(int index, int player) {
        cardsPlayed[player] = hands[player][index];
        hands[player][index] = null;
        repaint();
    }
    //so far these methods are useless
    public void mouseClicked(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {

    }

    public void mouseEntered(MouseEvent e) {

    }

    public void mouseExited(MouseEvent e) {

    }
    /*
     * used to decide where the user clicked and which card that corresponds too.
     * I used this way instead of overlapping JLabels with the pictures because
     * is allows the user to click on the whole card and not just a small part where
     * the JLabel is defined. Also ImageIcon is useless because you cannot add a
     * MouseListener to it, you have to add it to a new JPanel or a JMenu not just
     * the ImageIcon
     */
    private int getSelectedCard(int x, int y) {
        int validCards = 0;
        int selectedIndex = -1;
        for(int ctr = 0; ctr<13; ctr++)
            if(hands[0][ctr]!=null)
                validCards++;
        for(int ctr = 0; ctr<13; ctr++)
        {
            if(ctr<7)
            {
                if(x>=150+(ctr*73) && x<=150+((ctr+1)*73) && y>=465 && y<=561)
                    selectedIndex = ctr;
            }
            else
            {
                if(x>=180+((ctr-7)*73) && x<=180+((ctr-6)*73) && y>=563)
                    selectedIndex = ctr;
            }
        }
        //System.out.println(selectedIndex);
        return selectedIndex;
    }
    /*
     * handles the timer, seconds needs to be reformatted to show 0:00 not 0:0
     */
    public void actionPerformed(ActionEvent e) {
        if(state.getState()==0 && e.getActionCommand()!=null)
        {
        	if(e.getActionCommand().equals("New Game"))
        	{
        		state.setState(3);
        		mainMenu.setVisible(false);
        	}
        	else if(e.getActionCommand().equals("Settings"))
        	{
        		state.setState(1);
        		//mainMenu.setVisible(true);
        	}
        	else if(e.getActionCommand().equals("Stats"))
        	{
        		//state.setState(2);
        		//mainMenu.setVisible(false);
        	}
        	else if(e.getActionCommand().equals("exit"))
        	{
        		state.setState(10);
        		mainMenu.dispose();
        	}
        }
        if(state.getState()== 5)
        {
        	try{
        		tempBet = Integer.parseInt(e.getActionCommand());
        	}catch(Exception e1){
        		tempBet = -1;
        	}
        }
        if(state.getState()>2)
        {
        	if((sec+1)%60==0)
        	{
        		sec = 0;
        		min++;
        	}
        	else
        		sec++;
        	time = min+":"+sec;
        	repaint();
        }
    }
    /*
     * updates the hands in Board to that of what Spades says the official hands are
     */
    private void setHands(State s) {
    	s.deal();
        for(int ctr = 0; ctr<4; ctr++)
            hands[ctr] = s.getHand(ctr);
    }
    /*
     * handles the GUI for getting a bet from the player
     * MAJOR ISSUE! need to ensure a bet is received instead of being able to click cancel.
     */
    JFrame playerBet;// = new JFrame("Please place you bet");
    int tempBet = -1;
    private int getPlayerBet() {
    	spades.setEnabled(false);
    	playerBet = new JFrame("Please place you bet");
    	playerBet.addWindowStateListener(this);
    	playerBet.setSize(246,245);
    	playerBet.setLocation(getWidth()/2-115+190, getHeight()/2-160+40);
    	playerBet.setResizable(false);
    	playerBet.setLayout(new GridLayout(3,4));
    	playerBet.setAlwaysOnTop(true);
    	playerBet.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
    	playerBet.addWindowListener(this);
		JButton t = new JButton("nil");
		t.setActionCommand("0");
		t.addActionListener(this);
		playerBet.add(t);
		for(int ctr = 1; ctr<14; ctr++)
		{
			JButton temp = new JButton(""+ctr);
			temp.setActionCommand(""+ctr);
			temp.addActionListener(this);
			playerBet.add(temp);
		}
		
		playerBet.setVisible(true);
    	while(tempBet==-1)
    	{
    		
    	}
    	spades.setEnabled(true);
    	spades.setVisible(true);
    	playerBet.dispose();
    		return tempBet;
    }
    /*
     * used to pause after each card is played so the player can see the game progression
     */
    private void pause()
    {
    	try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
    }
    /*
     * ensures the card the user is trying to click is an allowable card based on current play status
     */
    private boolean isValidPlay(Card c)
    {
    	if(c!= null && c.getSuit()==0 && suitLed==4 && state.spadesAllowed==false)
    		return false;
    	if(c!= null && c.getSuit()==suitLed || suitLed == 4)
    		return true;
    	for(int ctr = 0; ctr<13; ctr++)
    	{
    		if(hands[0][ctr]!=null && hands[0][ctr].getSuit()==suitLed)
    			return false;
    	}
    	return true;
    }

	@Override
	public void windowActivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowClosed(WindowEvent arg0) {
		if(state.getState()==1)
		{
			state.setState(0);
		}
	}

	@Override
	public void windowClosing(WindowEvent arg0) {

	}

	@Override
	public void windowDeactivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowDeiconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowIconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
	}

	@Override
	public void windowOpened(WindowEvent arg0) {
	}

	@Override
	public void windowStateChanged(WindowEvent evt) {
		int oldState = evt.getOldState();
        int newState = evt.getNewState();

        if ((oldState & Frame.ICONIFIED) == 0
            && (newState & Frame.ICONIFIED) != 0) {
            System.out.println("Frame was iconized");
        }
		else if ((oldState & Frame.ICONIFIED) != 0
            && (newState & Frame.ICONIFIED) == 0) {
			if(evt.getSource()==playerBet)
			{
				System.out.println("Frame was deiconized by playerBet");
				spades.setEnabled(true);
				spades.setVisible(true);
				spades.toBack();
				spades.setEnabled(false);
				playerBet.setVisible(true);
				playerBet.toFront();
			}
			if(evt.getSource()==settings)
			{
				System.out.println("Frame was deiconized by settings");
				mainMenu.setEnabled(true);
				mainMenu.setVisible(true);
				mainMenu.toBack();
				mainMenu.setEnabled(false);
				settings.setVisible(true);
				settings.toFront();
			}
        }
	}
    
}